home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / games / larn12s.arc / LARN.ARC / MONSTER.C < prev    next >
C/C++ Source or Header  |  1987-10-28  |  44KB  |  1,426 lines

  1. /*
  2.  *    monster.c        Larn is copyrighted 1986 by Noah Morgan. 
  3.  *
  4.  *    This file contains the following functions:
  5.  *    ----------------------------------------------------------------------------
  6.  *
  7.  *    createmonster(monstno)         Function to create a monster next to the player
  8.  *        int monstno;
  9.  *
  10.  *    int cgood(x,y,itm,monst)    Function to check location for emptiness
  11.  *        int x,y,itm,monst;
  12.  *
  13.  *    createitem(it,arg)             Routine to place an item next to the player
  14.  *        int it,arg;
  15.  *
  16.  *    cast()                 Subroutine called by parse to cast a spell for the user
  17.  *
  18.  *    speldamage(x)         Function to perform spell functions cast by the player
  19.  *        int x;
  20.  *
  21.  *    loseint()            Routine to decrement your int (intelligence) if > 3
  22.  *
  23.  *    isconfuse()         Routine to check to see if player is confused
  24.  *
  25.  *    nospell(x,monst)    Routine to return 1 if a spell doesn't affect a monster
  26.  *        int x,monst;
  27.  *
  28.  *    fullhit(xx)            Function to return full damage against a monst (aka web)
  29.  *        int xx;
  30.  *
  31.  *    direct(spnum,dam,str,arg)    Routine to direct spell damage 1 square in 1 dir
  32.  *        int spnum,dam,arg;
  33.  *        char *str;
  34.  *
  35.  *    godirect(spnum,dam,str,delay,cshow)        Function to perform missile attacks
  36.  *        int spnum,dam,delay;
  37.  *        char *str,cshow;
  38.  *
  39.  *    ifblind(x,y)    Routine to put "monster" or the monster name into lastmosnt
  40.  *        int x,y;
  41.  *
  42.  *    tdirect(spnum)            Routine to teleport away a monster
  43.  *        int spnum;
  44.  *
  45.  *    omnidirect(sp,dam,str)  Routine to damage all monsters 1 square from player
  46.  *        int sp,dam;
  47.  *        char *str;
  48.  *
  49.  *    dirsub(x,y)            Routine to ask for direction, then modify x,y for it
  50.  *        int *x,*y;
  51.  *
  52.  *    vxy(x,y)              Routine to verify/fix (*x,*y) for being within bounds
  53.  *        int *x,*y;
  54.  *
  55.  *    dirpoly(spnum)        Routine to ask for a direction and polymorph a monst
  56.  *        int spnum;
  57.  *
  58.  *    hitmonster(x,y)     Function to hit a monster at the designated coordinates
  59.  *        int x,y;
  60.  *
  61.  *    hitm(x,y,amt)        Function to just hit a monster at a given coordinates
  62.  *        int x,y,amt;
  63.  *
  64.  *    hitplayer(x,y)         Function for the monster to hit the player from (x,y)
  65.  *        int x,y;
  66.  *
  67.  *    dropsomething(monst)     Function to create an object when a monster dies
  68.  *        int monst;
  69.  *
  70.  *    dropgold(amount)         Function to drop some gold around player
  71.  *        int amount;
  72.  *
  73.  *    something(level)         Function to create a random item around player
  74.  *        int level;
  75.  *
  76.  *    newobject(lev,i)         Routine to return a randomly selected new object
  77.  *        int lev,*i;
  78.  *
  79.  *  spattack(atckno,xx,yy)     Function to process special attacks from monsters
  80.  *      int atckno,xx,yy;
  81.  *
  82.  *    checkloss(x)     Routine to subtract hp from user and flag bottomline display
  83.  *        int x;
  84.  *
  85.  *    annihilate()   Routine to annihilate monsters around player, playerx,playery
  86.  *
  87.  *    newsphere(x,y,dir,lifetime)  Function to create a new sphere of annihilation
  88.  *        int x,y,dir,lifetime;
  89.  *
  90.  *    rmsphere(x,y)        Function to delete a sphere of annihilation from list
  91.  *        int x,y;
  92.  *
  93.  *    sphboom(x,y)        Function to perform the effects of a sphere detonation
  94.  *        int x,y;
  95.  *
  96.  *    genmonst()            Function to ask for monster and genocide from game
  97.  *
  98.  */
  99. #include "header.h"
  100.  
  101. struct isave    /* used for altar reality */
  102.     {
  103.     char type;    /* 0=item,  1=monster */
  104.     char id;    /* item number or monster number */
  105.     short arg;    /* the type of item or hitpoints of monster */
  106.     };
  107.  
  108. /*
  109.  *    createmonster(monstno)         Function to create a monster next to the player
  110.  *        int monstno;
  111.  *
  112.  *    Enter with the monster number (1 to MAXMONST+8)
  113.  *    Returns no value.
  114.  */
  115. createmonster(mon)
  116.     int mon;
  117.     {
  118.     register int x,y,k,i;
  119.     if (mon<1 || mon>MAXMONST+8)    /* check for monster number out of bounds */
  120.         {
  121.         beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;
  122.         }
  123.     while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */
  124.     for (k=rnd(8), i= -8; i<0; i++,k++)    /* choose direction, then try all */
  125.         {
  126.         if (k>8) k=1;    /* wraparound the diroff arrays */
  127.         x = playerx + diroffx[k];        y = playery + diroffy[k];
  128.         if (cgood(x,y,0,1))    /* if we can create here */
  129.             {
  130.             mitem[x][y] = mon;
  131.             hitp[x][y] = monster[mon].hitpoints;
  132. # ifdef DGK
  133.             stealth[x][y]=0;
  134.             know[x][y] &= ~KNOWHERE;
  135. # else
  136.             stealth[x][y]=know[x][y]=0;
  137. # endif
  138.             switch(mon)
  139.                 {
  140.                 case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;
  141.                 };
  142.             return;
  143.             }
  144.         }
  145.     }
  146.  
  147. /*
  148.  *    int cgood(x,y,itm,monst)      Function to check location for emptiness
  149.  *        int x,y,itm,monst;
  150.  *
  151.  *    Routine to return TRUE if a location does not have itm or monst there
  152.  *    returns FALSE (0) otherwise
  153.  *    Enter with itm or monst TRUE or FALSE if checking it
  154.  *    Example:  if itm==TRUE check for no item at this location
  155.  *              if monst==TRUE check for no monster at this location
  156.  *    This routine will return FALSE if at a wall or the dungeon exit on level 1
  157.  */
  158. int cgood(x,y,itm,monst)
  159.     register int x,y;
  160.     int itm,monst;
  161.     {
  162.     if ((y>=0) && (y<=MAXY-1) && (x>=0) && (x<=MAXX-1)) /* within bounds? */
  163.       if (item[x][y]!=OWALL)    /* can't make anything on walls */
  164.         if (itm==0 || (item[x][y]==0))    /* is it free of items? */
  165.           if (monst==0 || (mitem[x][y]==0))    /* is it free of monsters? */
  166.             if ((level!=1) || (x!=33) || (y!=MAXY-1)) /* not exit to level 1 */
  167.               return(1);
  168.     return(0);
  169.     }
  170.  
  171. /*
  172.  *    createitem(it,arg)         Routine to place an item next to the player
  173.  *        int it,arg;
  174.  *
  175.  *    Enter with the item number and its argument (iven[], ivenarg[])
  176.  *    Returns no value, thus we don't know about createitem() failures.
  177.  */
  178. createitem(it,arg)
  179.     int it,arg;
  180.     {
  181.     register int x,y,k,i;
  182.     if (it >= MAXOBJ) return;    /* no such object */
  183.     for (k=rnd(8), i= -8; i<0; i++,k++)    /* choose direction, then try all */
  184.         {
  185.         if (k>8) k=1;    /* wraparound the diroff arrays */
  186.         x = playerx + diroffx[k];        y = playery + diroffy[k];
  187.         if (cgood(x,y,1,0))    /* if we can create here */
  188.             {
  189.             item[x][y] = it;  know[x][y]=0;  iarg[x][y]=arg;  return;
  190.             }
  191.         }
  192.     }
  193.  
  194. /*
  195.  *    cast()         Subroutine called by parse to cast a spell for the user
  196.  *
  197.  *    No arguments and no return value.
  198.  */
  199. static char eys[] = "\nEnter your spell: ";
  200. cast()
  201.     {
  202.     register int i,j,a,b,d;
  203.     cursors();
  204.     if (c[SPELLS]<=0) {    lprcat("\nYou don't have any spells!");    return;    }
  205.     lprcat(eys);        --c[SPELLS];
  206.     while ((a=getchar())=='D')
  207.         { seemagic(-1); cursors();  lprcat(eys); }
  208.     if (a=='\33') goto over; /*    to escape casting a spell    */
  209.     if ((b=getchar())=='\33') goto over; /*    to escape casting a spell    */
  210.     if ((d=getchar())=='\33')
  211.         { over: lprcat(aborted); c[SPELLS]++; return; } /*    to escape casting a spell    */
  212. #ifdef EXTRA
  213.     c[SPELLSCAST]++;
  214. #endif
  215.     for (lprc('\n'),j= -1,i=0; i<SPNUM; i++) /*seq search for his spell, hash?*/
  216.         if ((spelcode[i][0]==a) && (spelcode[i][1]==b) && (spelcode[i][2]==d))
  217.             if (spelknow[i])
  218.                 {  speldamage(i);  j = 1;  i=SPNUM; }
  219.  
  220.     if (j == -1) lprcat("  Nothing Happened ");
  221.     bottomline();
  222.     }
  223.  
  224. /*
  225.  *    speldamage(x)         Function to perform spell functions cast by the player
  226.  *        int x;
  227.  *
  228.  *    Enter with the spell number, returns no value.
  229.  *    Please insure that there are 2 spaces before all messages here
  230.  */
  231. speldamage(x)
  232.     int x;
  233.     {
  234.     register int i,j,clev;
  235.     int xl,xh,yl,yh;
  236.     register char *p,*kn,*pm;
  237.     if (x>=SPNUM) return;    /* no such spell */
  238.     if (c[TIMESTOP])  { lprcat("  It didn't seem to work"); return; }  /* not if time stopped */
  239.     clev = c[LEVEL];
  240.     if ((rnd(23)==7) || (rnd(18) > c[INTELLIGENCE]))
  241.         { lprcat("  It didn't work!");  return; }
  242.     if (clev*3+2 < x) { lprcat("  Nothing happens.  You seem inexperienced at this"); return; }
  243.  
  244.     switch(x)
  245.         {
  246. /* ----- LEVEL 1 SPELLS ----- */
  247.  
  248.         case 0:    if (c[PROTECTIONTIME]==0)    c[MOREDEFENSES]+=2; /* protection field +2 */
  249.                 c[PROTECTIONTIME] += 250;   return;
  250.  
  251.         case 1: i = rnd(((clev+1)<<1)) + clev + 3;
  252.                 godirect(x,i,(clev>=2)?"  Your missiles hit the %s":"  Your missile hit the %s",100,'+'); /* magic missile */
  253.  
  254.                 return;
  255.  
  256.         case 2:    if (c[DEXCOUNT]==0)    c[DEXTERITY]+=3; /*    dexterity    */
  257.                 c[DEXCOUNT] += 400;      return;
  258.  
  259.         case 3: i=rnd(3)+1;
  260.                 p="  While the %s slept, you smashed it %d times";
  261.             ws:    direct(x,fullhit(i),p,i); /*    sleep    */    return;
  262.  
  263.         case 4:    /*    charm monster    */